package com.kaguya.vams.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kaguya.vams.domain.Result;
import com.kaguya.vams.domain.entity.SysMenu;
import com.kaguya.vams.domain.entity.SysRole;
import com.kaguya.vams.domain.entity.SysRoleMenu;
import com.kaguya.vams.domain.entity.SysUserRole;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.Delete;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;


/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author kaguya
 * @since 2021-07-28
 */
@Slf4j
@RestController
@RequestMapping("/sys/role")
public class SysRoleController extends BaseController {

    @GetMapping("/list")
    @PreAuthorize("hasAuthority('sys:role:list')")
    public Result list(String name) {

        //条件 如果roleName存在则进行模糊查询
        QueryWrapper<SysRole> wr = new QueryWrapper<>();
        wr.like(StringUtils.isNotBlank(name), "name", name);
        //分页信息
        Page<SysRole> page = super.getPage();
        //数据库查询
        Page<SysRole> rolePage = roleService.page(page, wr);


        return Result.ok(rolePage);
    }

    /**
     * 根据id查找单条信息 注意：返回角色的所有菜单权限id
     *
     * @return
     */
    @GetMapping("/info/{rowId}")
    @PreAuthorize("hasAnyAuthority('sys:role:update','sys:role:perm')")
    public Result info(@PathVariable Long rowId) {
        //根据id查询
        SysRole role = roleService.getById(rowId);
        //根据roleId查询所有与其关联的menusId
        List<SysRoleMenu> list = roleMenuService.list(
                new QueryWrapper<SysRoleMenu>()
                        .select("menu_id")
                        .eq("role_id", role.getId()));

        List<Long> menuIds = list.stream().map(e -> e.getMenuId()).collect(Collectors.toList());

        //设置其权限id集合
        role.setMenuIds(menuIds);

        return Result.ok(role);
    }

    /**
     * 新增
     *
     * @return
     */
    @PostMapping("/save")
    @PreAuthorize("hasAuthority('sys:role:save')")
    public Result save(@RequestBody SysRole role) {
        //调用方法，新增
        roleService.save(role);
        return Result.ok();
    }

    /**
     * 分配权限
     *
     * @return
     */
    @Transactional
    @PutMapping("/setPerm")
    @PreAuthorize("hasAuthority('sys:role:perm')")
    public Result setPerm(@Validated @RequestBody SysRole role) {

        //前台选中的新的权限id集合
        List<Long> menuIds = role.getMenuIds();

        //转换成SysRoleMenu
        List<SysRoleMenu> rmList = new ArrayList<>();
        menuIds.stream().forEach(e -> {
            SysRoleMenu temp = new SysRoleMenu();
            temp.setRoleId(role.getId());
            temp.setMenuId(e);

            rmList.add(temp);
        });
        //清空该角色原有权限 - 根据id删除角色权限关系表
        roleMenuService.remove(new QueryWrapper<SysRoleMenu>().eq("role_id", role.getId()));
        //重新添加分配该角色权限 - 根据传来的值批量新增角色权限关系表
        roleMenuService.saveBatch(rmList);

        //清空与该角色有关的用户的权限缓存信息
        userService.clearUserAuthorityInfoByRoleId(role.getId());

        return Result.ok();
    }

    /**
     * 修改
     *
     * @return
     */
    @PutMapping("/update")
    @PreAuthorize("hasAuthority('sys:role:update')")
    public Result update(@Validated @RequestBody SysRole role) {

        boolean update = roleService.updateById(role);

        //修改后，清除与其关联的权限缓存
        userService.clearUserAuthorityInfoByRoleId(role.getId());

        log.info("修改" + (update == true ? "成功" : "失败"));

        return update == true ? Result.ok() : Result.fail();
    }

    /**
     * 删除一条
     *
     * @return
     */
    @Transactional
    @DeleteMapping("/delete/{rowId}")
    @PreAuthorize("hasAuthority('sys:role:delete')")
    public Result delete(@PathVariable Long rowId) {

        //根据id删除
        roleService.removeById(rowId);
        //删除角色菜单关联表
        roleMenuService.remove(new QueryWrapper<SysRoleMenu>().eq("role_id",rowId));
        //删除用户角色关联表
        userRoleService.remove(new QueryWrapper<SysUserRole>().eq("role_id",rowId));
        //清空与其有关的用户的权限缓存
        userService.clearUserAuthorityInfoByRoleId(rowId);
        return Result.ok();
    }

    /**
     * 批量删除
     *
     * @return
     */
    @Transactional
    @DeleteMapping("/batchRemove")
    @PreAuthorize("hasAuthority('sys:role:delete')")
    public Result batchRemove(@RequestBody Long[] idList) {
        List<Long> list = Arrays.asList(idList);
        //根据id删除
        roleService.removeByIds(list);


        //删除角色菜单关联表
        roleMenuService.remove(new QueryWrapper<SysRoleMenu>().in("role_id",list));
        //删除用户角色关联表
        userRoleService.remove(new QueryWrapper<SysUserRole>().in("role_id",list));
        //清空与其有关的用户的权限缓存
        list.forEach( id -> {
            userService.clearUserAuthorityInfoByRoleId(id);
        });

        return Result.ok();
    }
}
